package com.itheima.bos.realm;

import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.itheima.bos.domain.system.Permission;
import com.itheima.bos.domain.system.Role;
import com.itheima.bos.domain.system.User;
import com.itheima.bos.service.system.IRoleService;
import com.itheima.bos.service.system.IUserService;
import com.itheima.bos.service.system.IPermissionService;

public class BosRealm extends AuthorizingRealm {
	
	@Autowired
	private  IUserService userServiceimpl;
	
	@Autowired
	private IRoleService roleServiceImpl;
	
	@Autowired
	private IPermissionService permissionServiceImpl;

	@Override
	//授权的方法
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		
		//创建授权对象(可以说是一个存储授权的集合对象)
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		//根据登录的用户查询对应角色的权限
		Subject subject = SecurityUtils.getSubject();
		
		User user = (User) subject.getPrincipal();
		
		//调用业务层查询角色
		List<Role> roles=roleServiceImpl.findByUser(user);
		for (Role role : roles) {
			//每查询一个认证的对象就对该对象授权
			authorizationInfo.addRole(role.getKeyword());
		}
		
		//调用业务层查询权限
		List<Permission> permissions=permissionServiceImpl.findbyUser(user);
		
		for (Permission permission : permissions) {
			authorizationInfo.addStringPermission(permission.getKeyword());
		}
		return authorizationInfo;
		
	}

	@Override
	//认证的方法
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		
		//转换token
		UsernamePasswordToken usernamePasswordToken=(UsernamePasswordToken) token;
		
		//要通过用户名来得到用户
		User user = userServiceimpl.findByUsername(usernamePasswordToken.getUsername());
		
		if(user==null){
			//用户不存在
			
			return null;
		}else{
			//用户存在
			//1.期望登陆后保存在subject中的值
			//2.用户密码
			//3.realm名称
			return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
		}
	 }
}
